package sudoku;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class SudokuView extends JFrame {
    private final SudokuModel model;
    private final SudokuController controller;
    private GridPanel gridPanel;
    JButton[] numberButtons = new JButton[9];

    private final static Color backgroundColor = new Color(240, 240, 240);
    private final static Color lightColor = new Color(226, 235, 243);
    private final static Color sameColor = new Color(186, 221, 251);
    private final static Color gridColor = new Color(216, 216, 216);
    private final static Color alertColor = new Color(247, 206, 213);

    public SudokuView(SudokuController controller, SudokuModel model) {
        this.controller = controller;
        this.model = model;
        initializeUI();
    }

    private void initializeUI() {
        setTitle("Sudoku");
        setSize(452, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false); // 禁止调整窗口大小
        setLayout(new BorderLayout());

        // 初始化 9x9 宫格
        gridPanel = new GridPanel(this.model, this.controller);
        add(gridPanel, BorderLayout.CENTER);

        // 新增控制面板，包含 "New Game" 按钮和难度选择下拉框
        JPanel controlPanel = new JPanel(new BorderLayout());
        
        // 难度选择下拉框
        String[] difficultyLevels = {"Easy", "Medium", "Hard", "Super"};
        JComboBox<String> difficultyComboBox = new JComboBox<>(difficultyLevels);
        difficultyComboBox.setPreferredSize(new Dimension(120, 30));
        difficultyComboBox.setFont(new Font("Arial", Font.BOLD, 20)); // 设置字体
        difficultyComboBox.setBackground(backgroundColor); // 设置背景颜色
        difficultyComboBox.addActionListener(e -> {
            String selectedDifficulty = (String) difficultyComboBox.getSelectedItem();
            int holes = 30; // 默认 Easy
            if ("Medium".equals(selectedDifficulty)) {
                holes = 40;
            } else if ("Hard".equals(selectedDifficulty)) {
                holes = 50;
            } else if ("Super".equals(selectedDifficulty)) {
                holes = 55;
            }
            controller.generatePuzzle(holes); // 通过 Controller 生成题目
            updateUI();
        });
        controlPanel.add(difficultyComboBox, BorderLayout.WEST);

        // 新增 "Help" 按钮
        JButton helpButton = new JButton("Help");
        helpButton.setPreferredSize(new Dimension(100, 30));
        helpButton.setFont(new Font("Arial", Font.BOLD, 20)); // 设置字体
        helpButton.setBackground(backgroundColor); // 设置背景颜色
        helpButton.setFocusPainted(false); // 去除焦点边框
        helpButton.addActionListener(e -> {
            int answer = controller.aiSolve(model.getUserGrid()); // 调用 Controller 获取 AI 解决方案
            if (answer <= 0 ) {
                JOptionPane.showMessageDialog(this, "算法太菜没找到答案。本题应该是有解的，请再试试，或者重开另一题。",
                        "提示", JOptionPane.INFORMATION_MESSAGE);
            }
            updateUI();
        });
        controlPanel.add(helpButton, BorderLayout.CENTER);

        // "New Game" 按钮
        JButton newGameButton = new JButton("New Game");
        newGameButton.setPreferredSize(new Dimension(160, 30));
        newGameButton.setFont(new Font("Arial", Font.BOLD, 20)); // 设置字体
        newGameButton.setBackground(backgroundColor); // 设置背景颜色
        newGameButton.setFocusPainted(false); // 去除焦点边框
        newGameButton.addActionListener(e -> {
            String selectedDifficulty = (String) difficultyComboBox.getSelectedItem();
            int holes = 30; // 默认 Easy
            if ("Medium".equals(selectedDifficulty)) {
                holes = 40;
            } else if ("Hard".equals(selectedDifficulty)) {
                holes = 50;
            } else if ("Super".equals(selectedDifficulty)) {
                holes = 55;
            }
            controller.generatePuzzle(holes); // 通过 Controller 生成题目
            updateUI();
        });
        controlPanel.add(newGameButton, BorderLayout.EAST);

        // 初始化数字按钮
        JPanel buttonPanel = new JPanel(new GridLayout(1, 9));
        for (int i = 0; i < 9; i++) {
            numberButtons[i] = new JButton(String.valueOf(i + 1));
            numberButtons[i].setPreferredSize(new Dimension(50, 60)); // 设置按钮大小
            numberButtons[i].setFont(new Font("Arial", Font.BOLD, 20)); // 设置字体
            numberButtons[i].setBackground(backgroundColor); // 设置背景颜色
            numberButtons[i].setFocusPainted(false); // 去除焦点边框
            numberButtons[i].addActionListener(new NumberButtonListener());
            buttonPanel.add(numberButtons[i]);
        }

        // 将控制面板和数字按钮面板添加到界面
        add(controlPanel, BorderLayout.NORTH);
        add(buttonPanel, BorderLayout.SOUTH);
    }

    public void updateUI() {
        // 获取数字计数器
        int[] numberCounters = model.getNumberCount();
        // 遍历数字按钮，根据计数器设置按钮状态
        for (int i = 0; i < numberButtons.length; i++) {
            if (numberCounters[i] >= 9) {
                numberButtons[i].setEnabled(false); // 数字出现次数达到9次，按钮失效
            } else {
                numberButtons[i].setEnabled(true); // 否则恢复按钮可点击状态
            }
        }
        gridPanel.repaint(); // 触发 gridPanel 重绘
    }

    public void showGameOverMessage() {
        JOptionPane.showMessageDialog(this, "恭喜！你成功完成了数独游戏！",
                "游戏结束", JOptionPane.INFORMATION_MESSAGE);
    }

    private class NumberButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            JButton button = (JButton) e.getSource();
            int number = Integer.parseInt(button.getText());
            System.out.println("Selected number: " + number);
            controller.makeMove(model.getSelectedRow(), model.getSelectedCol(), number);
        }
    }

    private static class GridPanel extends JPanel {
        private final SudokuModel model;
        private final SudokuController controller;
        private final int CELL_SIZE = 50;

        public GridPanel(SudokuModel model, SudokuController controller) {
            this.model = model;
            this.controller = controller;
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    controller.resetAIGrids(); // 调用 Controller 的方法重置 AI 网格
                    int row = e.getY() / CELL_SIZE;
                    int col = e.getX() / CELL_SIZE;
                    System.out.println("Clicked cell: (" + row + ", " + col + ")");
                    controller.selectCell(row, col);
                }
            });
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            drawGameElements(g2d);
        }

        private void drawGameElements(Graphics2D g2d) {
            boolean[][] lightGrid;
            boolean[][] sameNumGrid;
            int answer = controller.getAnswer(); // 调用 Controller 获取 AI 答案
            if (answer > 0) {
                lightGrid = controller.getAILightGrid(); // 调用 Controller 获取 AI 高亮网格
                sameNumGrid = controller.getAISameNumGrid(); // 调用 Controller 获取 AI 相同数字网格
            } else {
                lightGrid = model.getLightGrid();
                sameNumGrid = model.getSameNumGrid();
            }

            int r = model.getSelectedRow();
            int c = model.getSelectedCol();
            for (int row = 0; row < 9; row++) {
                for (int col = 0; col < 9; col++) {
                    if (lightGrid[row][col]) {
                        g2d.setColor(lightColor);
                        g2d.fillRect(col * CELL_SIZE, row * CELL_SIZE, CELL_SIZE, CELL_SIZE);
                    }
                    if (sameNumGrid[row][col]) {
                        g2d.setColor(sameColor);
                        g2d.fillRect(col * CELL_SIZE, row * CELL_SIZE, CELL_SIZE, CELL_SIZE);
                    }
                    if (row == r && col == c) {
                        if (model.getBadMove()) {
                            g2d.setColor(alertColor);
                            g2d.fillRect(col * CELL_SIZE, row * CELL_SIZE, CELL_SIZE, CELL_SIZE);
                        }
                    }
                    g2d.setColor(gridColor);
                    g2d.drawRect(col * CELL_SIZE, row * CELL_SIZE, CELL_SIZE, CELL_SIZE);
                }
            }

            // 将9宫格分成9个子区域
            g2d.setColor(Color.BLACK);
            for (int i = 0; i <= 3; i++) {
                // 绘制横线
                g2d.drawLine(0, i * 3 * CELL_SIZE, 9 * CELL_SIZE, i * 3 * CELL_SIZE);
                // 绘制竖线
                g2d.drawLine(i * 3 * CELL_SIZE, 0, i * 3 * CELL_SIZE, 9 * CELL_SIZE);
            }

            g2d.setColor(Color.BLACK);
            g2d.setFont(new Font("Arial", Font.PLAIN, 36));
            int [][] grid = model.getUserGrid();
            for (int row = 0; row < 9; row++) {
                for (int col = 0; col < 9; col++) {
                    if (grid[row][col] != 0) {
                        g2d.drawString(String.valueOf(grid[row][col]), col * CELL_SIZE + 16, row * CELL_SIZE + 42);
                    }
                }
            }
        }
    }
}